package com.spring.framework.config.event.scheduled;

import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.PeriodicTrigger;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport;

/**
 * Spring 调度任务简单执行
 *
 * @author xuweizhi
 * @since 2021/07/09 17:21
 */
public class SimpleScheduleExample {

	public static class CornExpressionExample {
		public static void main(String[] args) {
			ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
			threadPoolTaskScheduler.initialize();
			threadPoolTaskScheduler.schedule(() -> System.out.println("cron"), new CronTrigger("*/2 * * * * ?"));
		}
	}

	public static class PeriodicTriggerExample {

		/**
		 * 接收固定周期的PeriodicTrigger，它可以的构造器可以指定一个周期时间以及一个全局的事件单位，可以通过setInitialDelay方法指定第
		 * 一次执行的延迟时间，通过setFixedRate方法来指示构造器中的周期应该是固定速率（fixed-rate）还是固定延迟（fixed-delay）。
		 * <p>
		 * 由于TaskScheduler接口已经定义了固定速率（fixed-rate）或固定延迟（fixed-delay）的调度任务方法，因此尽可能直接使用这些方法。
		 * PeriodicTrigger通常是在依赖Trigger的组件中使用。
		 * <p>
		 * 下面定义的任务在1秒之后开始执行，并且在上一次任务执行完毕和下一次执行开始中间间隔3秒，即固定延迟（fixed-delay），任务执行时间为1秒：
		 */
		public static void main(String[] args) {
			//设置上一次任务执行完毕和下一次执行开始中间间隔1秒
			PeriodicTrigger periodicTrigger = new PeriodicTrigger(3, TimeUnit.SECONDS);
			//设置任务第一次执行的延迟时间
			periodicTrigger.setInitialDelay(1);
			//设置为固定延迟（fixed-delay）的调度任务，这也是默认类型
			periodicTrigger.setFixedRate(false);

			ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
			threadPoolTaskScheduler.initialize();
			AtomicLong atomicLong = new AtomicLong(System.currentTimeMillis());
			System.out.println(0);
			threadPoolTaskScheduler.schedule(() -> {
				long newTime = System.currentTimeMillis();
				long time = newTime - atomicLong.get();
				atomicLong.set(newTime);
				System.out.println(time);
				LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
				long newTime2 = System.currentTimeMillis();
				long time2 = newTime2 - atomicLong.get();
				atomicLong.set(newTime2);
				System.out.println("任务执行时间: " + time2);
			}, periodicTrigger);
		}
	}

}
